import { PCMRecorder } from '../../utils/recorder'
import { getVisit, getPreChats, questionAnswer, recognition, reconsult, getDoc, modifyDoc, getTtsUrl } from "./api/api"

let innerAudio: WechatMiniprogram.InnerAudioContext
let playingIndex: number = -1   // 全局变量
let isManualStop = false  //表示 stop 是为了切换音频

Page({
  //右上角分享按钮
  onShareAppMessage() {
    return {
      title: '分享音频示例',
      path: `/pages/index/index?visitId=${this.visitId}`,
    }
  },
  data: {
    visitId: '',
    isFirst: false,
    selected: '',// 记录选中状态：first / again
    loadingFull: false,
    loadingFullText: '',
    isVoice: false, // 输入模式
    textValue: '',
    textLoading: false,
    messages: [] as Array<{ from: string, content: string; loading?: boolean; playing?: boolean, chatId: string }>,
    toView: '',//滚动条滚动到的项目
    imgMap: {
      me: '',
      bot: './image/robot.png'
    },
    recording: false, //是否按住录音
    preViewModalShow: false, //翻译预览弹框
    preViewTextValue: '',
    preViewTextLoading: false,
    talkDone: false,//对话结束
    hasReport: false,//显示报告
    scrollTop: 0,
    patientData: {} as any,
    doctorData: {} as any,
    reportData: {} as any,
    isEditReport: false, //编辑报告
    editReportData: {} as any,
    aiChatId: '' //要重新回答的问题ID
  },

  // 生命周期函数：页面加载
  async onLoad(options: Record<string, string>) {
    if (options.visitId) {
      this.setData({ visitId: options.visitId })
    } else {
      // 1970320127734439938  //已问诊
      // 1970320682846380034  //未问诊
      this.setData({ visitId: '1970320682846380034' })
    }
    this.setData({ loadingFull: true, loadingFullText: '加载中...' })

    try {
      const visitRes = await getVisit({
        visitId: this.data.visitId
      }) as any
      this.setData({
        patientData: {
          name: visitRes.data.patientName,
          sex: visitRes.data.gender,
          sexName: visitRes.data.genderName
        },
        doctorData: {
          deptName: visitRes.data.visitOrgName,
          name: visitRes.data.doctorName
        }
      })
      // 根据用户性别使用不同图标
      if (this.data.patientData.sex === '0') {
        this.setData({ ['imgMap.me']: './image/woman.png' })
      } else if (this.data.patientData.sex === '1') {
        this.setData({ ['imgMap.me']: '/image/man.png' })
      }

      if (visitRes.data.preStatus === 'consulted') {
        this.gotoViewReport()
      } else if (visitRes.data.preStatus === 'in_progress') {
        const preChatsRes = await getPreChats({
          visitId: this.data.visitId
        }) as any
        if (preChatsRes.data && preChatsRes.data.preChats) {
          preChatsRes.data.preChats.forEach((row: any) => {
            this.addMessage({
              from: this.getFrom(row.speaker),
              content: row.text,
              chatId: row.chatId,
            })
          });
        }
      } else {
        this.firstAsk()
      }
      this.setData({ loadingFull: false })
    } catch (error) {
      this.setData({ loadingFull: false })
    }
  },
  //初始话问诊
  firstAsk() {
    this.setData({ loadingFull: true, loadingFullText: '加载中...' })
    reconsult({
      visitId: this.data.visitId,
    }).then(() => {
      this.setData({ isFirst: true, selected: '', messages: [], talkDone: false, hasReport: false, reportData: {}, isEditReport: false, loadingFull: false })
      this.addMessage({
        from: 'bot',
        content: '您是初诊还是复诊？',
      })
    })
  },

  recorder: null as any,
  onReady() {
    this.initAudio()
    this.recorder = new PCMRecorder(async (base64) => {
      try {
        this.setData({ recording: false, preViewModalShow: true, preViewTextLoading: true })
        const res = await recognition({
          visitId: this.data.visitId,
          audio: base64
        })
        if (!res.data) {
          this.noVideoText()
        } else {
          this.setData({ preViewTextValue: res.data, preViewTextLoading: false })
        }
      } catch (err) {
        this.noVideoText()
      }
    })
    this.recorder.initCanvas('waveCanvas', 200, 50, this)
  },
  //初始化音频播放
  initAudio() {
    innerAudio = wx.createInnerAudioContext()
    innerAudio.onPlay(() => {
      if (playingIndex >= 0) {
        this.setData({
          [`messages[${playingIndex}].loading`]: false,
          [`messages[${playingIndex}].playing`]: true
        })
      }
    })
    innerAudio.onEnded(() => {
      this.resetAll()
    })
    innerAudio.onStop(() => {
      if (!isManualStop) {
        this.resetAll()
      }
      isManualStop = false
    })
    innerAudio.onError(() => {
      wx.showToast({ title: "播放出错", icon: "none" })
      this.resetAll()
    })
  },
  //播放音频
  async playaudio(e: any) {
    const index = e.currentTarget.dataset.index
    const msg = this.data.messages[index]
    // 如果点的是正在播放的，直接停止
    if (playingIndex === index && msg.playing) {
      innerAudio.stop()
      this.resetAll()
      return
    }
    // 切换音频
    isManualStop = true
    // 停止上一次音频
    innerAudio.stop()
    // 重置所有状态，并设置当前项 loading
    this.resetAll(index)
    // 延时播放，确保 stop 生效
    try {
      const res = await getTtsUrl({
        chatId: msg.chatId,
        text: msg.content,
      })
      innerAudio.src = res.data + '?t=' + Date.now()
      innerAudio.play()
    } catch (error) {
      this.resetAll()
    }
  },
  //停止所有播放状态
  resetAll(index = -1) {
    // 重置所有状态 + 设置当前项 loading
    const msgs = this.data.messages.map((m, i) => ({
      ...m,
      loading: i === index,
      playing: false
    }))
    this.setData({
      messages: msgs
    })
    playingIndex = index
  },

  //初诊复诊选择事件
  onSelect(e: any) {
    const type = e.currentTarget.dataset.type
    this.setData({ selected: type })
    this.onConfirm()
  },
  //初诊复诊确定事件
  onConfirm() {
    if (!this.data.selected) return
    let textValue
    if (this.data.selected === 'first') {
      textValue = '初诊'
    } else if (this.data.selected === 'again') {
      textValue = '复诊'
    }
    this.setData({ isFirst: false, textValue })
    this.sendText()
  },

  // 开始录音
  async startRecord() {
    this.setData({ recording: true })
    this.recorder.start()
  },
  // 停止录音并上传
  async stopRecord() {
    this.recorder.stop()
  },
  noVideoText() {
    wx.showToast({
      title: '未识别到语音',
      icon: 'error', // success、loading、none
      duration: 2000
    })
    this.setData({ preViewModalShow: false, preViewTextLoading: false })
  },
  //修改录音返回文字
  onTextVideoInput(e: WechatMiniprogram.Input) {
    this.setData({ preViewTextValue: e.detail.value })
  },
  closePreview() {
    this.setData({ preViewTextValue: '', preViewModalShow: false })
  },
  successPreview() {
    if (!this.data.preViewTextValue) {
      wx.showToast({
        title: '请输入文字',
        icon: 'error', // success、loading、none
        duration: 2000
      })
    } else {
      this.setData({ textValue: this.data.preViewTextValue })
      this.setData({ preViewTextValue: '', preViewModalShow: false })
      this.sendText()
    }
  },

  // 切换输入方式
  toggleInputMode() {
    this.setData({ isVoice: !this.data.isVoice })
  },
  // 文本输入
  onTextInput(e: WechatMiniprogram.Input) {
    this.setData({ textValue: e.detail.value })
  },

  // 发送文字
  async sendText() {
    const text = this.data.textValue.trim()
    if (!text) return
    // 先显示本地消息    
    this.addMessage({
      from: 'me',
      content: text,
    })
    this.setData({ textValue: '', textLoading: true, toView: 'msg-textLoading' })
    const params = {
      visitId: this.data.visitId,
      consultationType: this.data.selected,
      text,
    } as any
    if (this.data.aiChatId) {
      params.aiChatId = this.data.aiChatId
    }
    questionAnswer(params).then((res: any) => {
      this.setData({ aiChatId: '' })
      if (res.data.requiredDone === 'done') {
        this.setData({ textLoading: false, talkDone: true })
      } else {
        this.addMessage({
          from: 'bot',
          content: res.data.answer.text,
          chatId: res.data.answer.chatId,
        })
        const index = this.data.messages.length - 1;
        this.setData({ textLoading: false, toView: 'msg-' + index })
      }
    }).finally(() => {
      this.setData({ textLoading: false })
    })
  },
  //重新修改 修改问题
  editAnswer(e: any) {
    const index = e.currentTarget.dataset.index
    if (index === 1) {
      this.firstAsk()
    } else {
      const newMessages = this.data.messages.slice(0, index)
      this.setData({ messages: newMessages, talkDone: false, aiChatId: newMessages[index - 1].chatId })
    }
  },
  // 在界面显示消息
  addMessage(obj: any) {
    this.setData({
      messages: [
        ...this.data.messages,
        { ...obj, playing: false, loading: false }
      ]
    })
  },

  //查看报告
  async gotoViewReport() {
    this.setData({ loadingFull: true, loadingFullText: '正在生成预问诊报告，请稍等...' })
    try {
      const docRes = await getDoc({
        visitId: this.data.visitId
      }) as any
      docRes.data.docData.forEach((row: any) => {
        if (row.hasOwnProperty("modifyValue")) {
          row.fieldValue = row.modifyValue
        }
      });
      this.setData({
        scrollTop: 0, hasReport: true, loadingFull: false,
        reportData: {
          name: docRes.data.patientName,
          sexName: docRes.data.genderName,
          age: docRes.data.age === '' ? '-' : docRes.data.age,
          type: this.getConsultationTypeName(docRes.data.consultationType),
          time: docRes.data.preConsultationTime,
          docList: docRes.data.docData
        },
      })
    } catch (error) {
      this.setData({ loadingFull: false })
    }
  },
  //编辑报告
  editReport() {
    this.setData({
      scrollTop: 0,
      isEditReport: true,
      editReportData: JSON.parse(JSON.stringify(this.data.reportData))
    })
  },
  //编辑报告返回
  back() {
    this.setData({ scrollTop: 0, isEditReport: false })
  },
  //编辑报告输入框输入事件
  onDocInput(e: any) {
    const index = e.currentTarget.dataset.index
    const value = e.detail.value
    const { editReportData } = this.data
    editReportData.docList[index].fieldValue = value
    this.setData({
      editReportData
    })
  },
  //保存报告
  async save() {
    this.setData({ loadingFull: true, loadingFullText: '正在保存预问诊报告，请稍等...' })
    try {
      await modifyDoc({
        visitId: this.data.visitId,
        modifyList: this.data.editReportData.docList
      })  
      wx.showToast({
        title: '报告修改成功',
        icon: 'success',
        duration: 2000
      })
      this.setData({
        scrollTop: 0,
        loadingFull: false,
        isEditReport: false,
        reportData: JSON.parse(JSON.stringify(this.data.editReportData))
      })
    } catch (error) {
      this.setData({ loadingFull: false })
    }
  },

  getFrom(speaker: string) {
    let str = ''
    switch (speaker) {
      case '1':
        str = 'bot'
        break;
      case '0':
        str = 'me'
        break;
      default:
        break;
    }
    return str
  },
  getConsultationTypeName(consultationType: string) {
    let textValue
    if (consultationType === 'first') {
      textValue = '初诊'
    } else if (consultationType === 'again') {
      textValue = '复诊'
    }
    return textValue
  }
})
